/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

/**
 * {@code Short}类在对象中包装了基本类型为{@code short}的值.
 * 一个{@code Short}类型的对象只包含一个{@code short}类型的字段.
 *
 * <p>另外,该类提供了多个方法,可以将{@code short}转换为{@code String},将{@code String}转换为{@code short},
 * 同时还提供了其他一些处理{@code short}时有用的常量和方法.
 *
 * @author  Nakul Saraiya
 * @author  Joseph D. Darcy
 * @see     java.lang.Number
 * @since   JDK1.1
 */
public final class Short extends Number implements Comparable<Short> {

    /**
     * {@code short}{@code short}能存储的最小值的常量,-2<sup>15</sup>.
     */
    public static final short   MIN_VALUE = -32768;

    /**
     *{@code short}{@code short}能存储的最大值的常量,2<sup>15</sup>-1.
     */
    public static final short   MAX_VALUE = 32767;

    /**
     * 代表基本类型{@code short}的{@code Class}实例.
     */
    @SuppressWarnings("unchecked")
    public static final Class<Short>    TYPE = (Class<Short>) Class.getPrimitiveClass("short");

    /**
     * 返回一个代表指定{@code short}的新的{@code String}对象.基数假定为10.
     *
     * @param s 要转换的{@code short}
     * @return 代表指定{@code short}的字符串
     * @see java.lang.Integer#toString(int)
     */
    public static String toString(short s) {
        return Integer.toString((int)s, 10);
    }

    /**
     * 将字符串参数解析为由第二个参数指定的基数中的有符号的{@code short}.
     * 除了第一个字符可以是表示负值的 ASCII符号中的减号 {@code '-'} ({@code '\u005Cu002D'})
     * 或者表示正值的ASCII中的加号 {@code '+'} ({@code '\u005Cu002B'}) 之外,
     * 该字符串中的字符必须都是指定基数(这取决于{@link java.lang.Character#digit(char,int)} 是否返回非负值)的数字.
     * 返回得到的{@code short}值.
     *
     * <p>如果出现以下情形之一,则抛出一个类型为{@code NumberFormatException}的异常:
     * <ul>
     * <li> 第一个参数为{@code null}或者长度为0的字符串.
     *
     * <li> 基数小于{@link java.lang.Character#MIN_RADIX}或者大于{@link java.lang.Character#MAX_RADIX}.
     *
     * <li>除了在字符串长度超过1的情况下第一个字符可能是减号{@code '-'} ({@code '\u005Cu002D'})或者加号{@code '+'} ({@code '\u005Cu002B'}) 之外
     * 字符串中的任何字符不是指定基数的数字.
     *
     * <li> 字符串所表示的值不是{@code short}类型的值.
     * </ul>
     *
     * @param s         包含要解析的 {@code short} 表示形式的  {@code String}
     * @param radix     解析 {@code s} 时要采用的基数
     * @return          由指定基数中的字符串参数表示的 {@code short}.
     * @throws          NumberFormatException 如果{@code String}不包含可解析的 {@code short}.
     */
    public static short parseShort(String s, int radix)
        throws NumberFormatException {
        int i = Integer.parseInt(s, radix);
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
        return (short)i;
    }

    /**
     * 将字符串参数解析为有符号的十进制{@code short}.
     * 除了第一个字符可以是表示负值的 ASCII符号中的减号 {@code '-'} ({@code '\u005Cu002D'})
     * 或者表示正值的ASCII中的加号 {@code '+'} ({@code '\u005Cu002B'}) 之外,
     * 该字符串中的字符必须都是十进制数字.
     * 返回得到的{@code short}值,此值与用该参数和基数10作为参数的{@link #parseShort(java.lang.String, int)}方法得到的值相同.
     *
     * @param s 包含要解析的{@code short}表示形式的{@code String}
     * @return  参数(十进制)表示的{@code short}值.
     * @throws  NumberFormatException 如果该字符串不包含可解析的{@code short}.
     */
    public static short parseShort(String s) throws NumberFormatException {
        return parseShort(s, 10);
    }

    /**
     * 返回一个{@code Short}对象,该对象保持从指定的{@code String}中提取的值,
     * 该值是在使用第二个参数给出的基数对指定字符串进行解析时提取的
     * 第一个参数被解析为表示在使用第二个参数所指定基数时的一个有符号的{@code short},
     * 此值与用该参数作为参数的  {@link #parseShort(java.lang.String,int)} 方法得到的值相同.
     * 结果是一个表示该字符串所指定的{@code short}值的{@code Short}对象.
     *
     * <p>换句话说, 此方法返回一个{@code Short}对象,它的值等于:
     *
     * <blockquote>
     *  {@code new Short(Short.parseShort(s, radix))}
     * </blockquote>
     *
     * @param s         要解析的字符串
     * @param radix     将在解析{@code s}时使用的基数
     * @return          保持指定基数中的字符串参数所表示的值的{@code Short}对象.
     * @throws          NumberFormatException 如果{@code String}不包含可解析的{@code short}.
     *
     */
    public static Short valueOf(String s, int radix)
        throws NumberFormatException {
        return valueOf(parseShort(s, radix));
    }

    /**
     * 返回一个保持指定{@code String}所给出的值的{@code Short}对象.
     * 该参数被解析为表示一个有符号的十进制{@code short},
     * 此值与用该参数作为参数的 {@link #parseShort(java.lang.String)} 方法得到的值相同.
     * 结果是一个表示该字符串所指定的{@code short}值的{@code Short}对象
     *
     * <p>换句话说, 此方法返回一个{@code Short}对象,它的值等于:
     *
     * <blockquote>
     *  {@code new Short(Short.parseShort(s))}
     * </blockquote>
     *
     * @param s 要解析的字符串
     * @return  保持指定基数中的字符串参数所表示的值的{@code Short}对象.
     * @throws  NumberFormatException 如果{@code String}不包含可解析的{@code short}.
     */
    public static Short valueOf(String s) throws NumberFormatException {
        return valueOf(s, 10);
    }

    private static class ShortCache {
        private ShortCache(){}

        static final Short cache[] = new Short[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Short((short)(i - 128));
        }
    }

    /**
     * 返回一个代表指定{@code short}值的{@code Short}实例.
     * 如果不需要新的{@code Short}实例,则通常应该优先采用此方法,而不是构造方法{@link #Short(short)},
     * 因为此方法很会缓存经常请求的值,这很可能会显著提高空间和时间性能.
     *
     * 该方法总是会缓存 -128 到 127 之间的值,
     * 可能会缓存该范围之外的值.
     *
     * @param  s 一个short值.
     * @return 一个代表{@code s}的{@code Short}实例.
     * @since  1.5
     */
    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }

    /**
     * 将一个{@code String}解码为{@code Short}.
     * 接受通过以下语法给出的十进制、十六进制和八进制数:
     *
     * <blockquote>
     * <dl>
     * <dt><i>可解码字符串:</i>
     * <dd><i>符号<sub>可选</sub> DecimalNumeral</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0x} <i>HexDigits</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0X} <i>HexDigits</i>
     * <dd><i>符号<sub>可选</sub></i> {@code #} <i>HexDigits</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0} <i>OctalDigits</i>
     *
     * <dt><i>符号:</i>
     * <dd>{@code -}
     * <dd>{@code +}
     * </dl>
     * </blockquote>
     *
     * <i>DecimalNumeral</i>, <i>HexDigits</i>, 和 <i>OctalDigits</i>
     * 在<cite>The Java&trade; Language Specification</cite>的3.10.1节中有定义,
     * 除了不接受数字中的下划线之外(译者注:Java7开始数字中可添加下划线以提高可阅读性,但是在这里该方法不支持这种形式的数字).
     *
     * <p>对(可选)负号和/或基数说明符("{@code 0x}", "{@code 0X}","{@code #}",或者前导0)后面的字符序列进行解析
     * 就如同用{@code Short.parseShort} 方法以及指定的基数(10, 16, 或8)来解析一样.
     * 该字符序列必须表示为一个正值,否则将会抛出{@link NumberFormatException}.
     * 如果指定{@code String}的第一个字符是减号,那么返回结果是负的.
     * {@code String}中不允许存在空白字符.
     *
     * @param     nm 要解码的{@code String}.
     * @return    保持 {@code nm} 所表示的{@code short}值的{@code Short}对象
     * @throws    NumberFormatException  如果 {@code String} 不包含可解析的 {@code short}.
     * @see java.lang.Short#parseShort(java.lang.String, int)
     */
    public static Short decode(String nm) throws NumberFormatException {
        int i = Integer.decode(nm);
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                    "Value " + i + " out of range from input " + nm);
        return valueOf((short)i);
    }

    /**
     *  {@code Short}的值.
     *
     * @serial
     */
    private final short value;

    /**
     * 构造一个新分配的代表指定{@code short}值的{@code Short}对象.
     *
     * @param value     将由{@code Short}来表示的值.
     */
    public Short(short value) {
        this.value = value;
    }

    /**
     * 构造一个新分配的{@code Short}对象, 用来表示 {@code String} 参数所指示的 {@code short} 值.
     * 将字符串转换为 {@code short} 值, 转换方式与基数为 10 的 {@code parseShort} 方法所用的方式完全相同
     *
     * @param s 要被转换成{@code Short}的{@code String}.
     * @throws  NumberFormatException 如果{@code String}不包含一个可解析的{@code short}.
     * @see     java.lang.Short#parseShort(java.lang.String, int)
     */
    public Short(String s) throws NumberFormatException {
        this.value = parseShort(s, 10);
    }

    /**
     * 将此{@code Short}的值经过收缩基本转换(Narrowing Primitive Conversions)后作为一个{@code byte}返回.
     * @jls 5.1.3 Narrowing Primitive Conversions
     */
    public byte byteValue() {
        return (byte)value;
    }

    /**
     * 将此{@code Short}的值作为一个{@code short}返回.
     */
    public short shortValue() {
        return value;
    }

    /**
     * 将此{@code Short}的值经过扩展基本转换(Widening Primitive Conversions)后作为一个{@code int}返回.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public int intValue() {
        return (int)value;
    }

    /**
     * 将此{@code Short}的值经过扩展基本转换(Widening Primitive Conversions)后作为一个{@code long}返回.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public long longValue() {
        return (long)value;
    }

    /**
     * 将此{@code Short}的值经过扩展基本转换(Widening Primitive Conversions)后作为一个{@code float}返回.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public float floatValue() {
        return (float)value;
    }

    /**
     * 将此{@code Short}的值经过扩展基本转换(Widening Primitive Conversions)后作为一个{@code double}返回.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public double doubleValue() {
        return (double)value;
    }

    /**
     * 返回一个代表此{@code Short}的值的{@code String}对象.
     * 该值被转换为有符号的十进制数字表现形式并以字符串的形式返回,
     * 等同于{@code short}值作为参数的{@link java.lang.Short#toString(short)}方法.
     *
     * @return  该对象的十进制的值的字符串表现形式.
     */
    public String toString() {
        return Integer.toString((int)value);
    }

    /**
     * 返回该{@code Short}的hash code;等价于调用 {@code intValue()}方法的结果.
     *
     * @return 该{@code Short}的hash code值.
     */
    @Override
    public int hashCode() {
        return Short.hashCode(value);
    }

    /**
     * 返回一个{@code short}值的hash code;等同于{@code Short.hashCode()}.
     *
     * @param value 需要计算hash code的short值
     * @return 一个{@code short}值的hash code值.
     * @since 1.8
     */
    public static int hashCode(short value) {
        return (int)value;
    }

    /**
     * 将当前对象同指定对象进行比较.
     * 当且仅当参数不为{@code true}并且是一个和此对象包含相同{@code short}值的{@code Short}对象时,返回结果为{@code true}.
     *
     * @param obj       要比较的对象.
     * @return          如果对象相同,那么返回{@code true};否则返回{@code false}.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Short) {
            return value == ((Short)obj).shortValue();
        }
        return false;
    }

    /**
     * 从数值上比较两个{@code Short}对象.
     *
     * @param   anotherShort   要比较的{@code Short}.
     * @return  如果此{@code Short}对象等于参数{@code Short},那么返回结果为{@code 0};
     *          如果此{@code Short}对象数值上小于参数{@code Short},那么返回结果为一个小于{@code 0}的值;
     *          如果此{@code Short}对象数值上大于参数{@code Short},那么返回结果为一个大于{@code 0}的值(有符号对比).
     * @since   1.2
     */
    public int compareTo(Short anotherShort) {
        return compare(this.value, anotherShort.value);
    }

    /**
     * 从数值上比较两个{@code short}值.
     * 返回值等同与以下代码的返回值:
     * <pre>
     *    Short.valueOf(x).compareTo(Short.valueOf(y))
     * </pre>
     *
     * @param  x 要比较的第一个{@code short}
     * @param  y 要比较的第二个{@code short}
     * @return 如果{@code x == y},那么返回{@code 0};
     *         如果{@code x < y},那么返回一个小于{@code 0}的值;
     *         如果{@code x > y},那么返回一个大于{@code 0}的值.
     * @since 1.7
     */
    public static int compare(short x, short y) {
        return x - y;
    }

    /**
     * 以二进制补码形式表示一个 {@code short} 值的位数.
     * @since 1.5
     */
    public static final int SIZE = 16;

    /**
     * 以二进制补码形式表示一个 {@code short} 值的字节数.
     *
     * @since 1.8
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /**
     * 返回通过反转指定{@code short}值的二进制补码表示形式中字节的顺序而获得的值.
     *
     * @param i 要反转的值
     * @return 返回通过反转(或者交换,效果相同)指定 {@code short} 值中的字节而获得的值.
     * @since 1.5
     */
    public static short reverseBytes(short i) {
        return (short) (((i & 0xFF00) >> 8) | (i << 8));
    }


    /**
     * 通过无符号转换将参数转换为{@code int}.
     * 在无符号转换为{@code int}的过程中, {@code int}的高位的16 bit为0,低位的16 bit等于{@code short}的 bit.
     *
     * 因此, 0 和正的 {@code short} 值被映射为一个等于{@code int}值的数字,
     * 负的{@code short} 值映射为一个等于{@code int}值加上2<sup>16</sup>的数字.
     *
     * @param  x 要转换为无符号 {@code int}的值
     * @return 参数通过无符号转换而得到的{@code int}
     * @since 1.8
     */
    public static int toUnsignedInt(short x) {
        return ((int) x) & 0xffff;
    }

    /**
     * 通过无符号转换将参数转换为{@code long}.
     * 在无符号转换为{@code long}的过程中, {@code long}的高位的48 bit为0,低位的16 bit等于{@code short}的 bit.
     * 因此, 0 和正的 {@code short} 值被映射为一个等于{@code int}值的数字,
     * 负的{@code short} 值映射为一个等于{@code int}值加上2<sup>16</sup>的数字.
     *
     * 因此, 0 和正的 {@code short} 值被映射为一个等于{@code long}值的数字,
     * 负的{@code short} 值映射为一个等于{@code long}值加上2<sup>16</sup>的数字.
     *
     * @param  x 要转换为无符号 {@code long}的值
     * @return 参数通过无符号转换而得到的{@code long}
     * @since 1.8
     */
    public static long toUnsignedLong(short x) {
        return ((long) x) & 0xffffL;
    }

    /** 使用来自 JDK 1.1 的serialVersionUID,以便兼容 */
    private static final long serialVersionUID = 7515723908773894738L;
}
